package com.haisen.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.haisen.core.utils.InsertBatch;
import com.haisen.core.utils.MyMapper;
import com.haisen.core.utils.PageResultSet;
import com.haisen.dataobject.dto.RankDto;
import com.haisen.dataobject.entity.Rank;
import com.haisen.dataobject.mapper.base.RankMapper;
import com.haisen.dataobject.query.RankQuery;
import com.haisen.poi.basic_poi.BigExcelUtil;
import com.haisen.service.RankServcie;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.weekend.Weekend;
import tk.mybatis.mapper.weekend.WeekendCriteria;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class RankServcieImpl implements RankServcie {

    @Autowired
    private RankMapper rankMapper;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    private InsertBatch<Rank> batchAdd = null;


    @Override
    public void create(Rank rank) {

        if(!StringUtils.isEmpty(rank.getInOut()) && rank.getInOut() < 0){
            rank.setCore((new BigDecimal(0)).subtract(rank.getCore()));
        } else {
           rank.setInOut(1);
        }
        rankMapper.insertSelective(rank);
    }

    @Override
    public void update(Rank rank) {
        rankMapper.updateByPrimaryKeySelective(rank);
    }

    @Override
    public void delete(Long[] ids) {
        Weekend<Rank> example = Weekend.of(Rank.class);
        WeekendCriteria<Rank,Object> criteria = example.weekendCriteria();
        criteria.andIn(Rank::getId, Arrays.asList(ids));
        rankMapper.deleteByExample(example);
    }

    @Override
    public void createbatch(List<Rank> rankList) {
        SqlSession sqlSession= sqlSessionFactory.openSession(ExecutorType.BATCH);
        MyMapper<Rank> myMapper = (MyMapper<Rank>) sqlSession.getMapper(RankMapper.class);
        batchAdd = new InsertBatch<>();
        batchAdd.insertBatch(sqlSession,myMapper, rankList);
    }

    @Override
    public List<Rank> find(RankQuery rankQuery) {
        Weekend<Rank> example = Weekend.of(Rank.class);
        WeekendCriteria<Rank,Object> criteria = example.weekendCriteria();
        if (!StringUtils.isEmpty(rankQuery.getSearchDate())){
            criteria.andGreaterThanOrEqualTo(Rank::getCdate, rankQuery.getBeginDate());
            criteria.andLessThanOrEqualTo(Rank::getCdate, rankQuery.getEndDate());
        }
        if (!StringUtils.isEmpty(rankQuery.getUsername())){
            criteria.andEqualTo(Rank::getUsername, rankQuery.getUsername());
        }

       return rankMapper.selectByExample(example);
    }


    @Override
    public BigDecimal findMyselfScore(String userName) {
        Weekend<Rank> example = Weekend.of(Rank.class);
        WeekendCriteria<Rank,Object> criteria = example.weekendCriteria();
        criteria.andEqualTo(Rank::getUsername,userName);
        Optional<BigDecimal> optional = rankMapper.selectByExample(example)
                 .stream().map(Rank::getCore).reduce((x,y)->x.add(y));
       return optional.orElse(new BigDecimal(0));
    }

    /**
     * 排名明细数据
     * @param rankQuery
     * @return
     */
    @Override
    public PageResultSet<Rank> findDetail(RankQuery rankQuery) {
        if (!StringUtils.isEmpty(rankQuery.getOrderBy())){
            PageHelper.orderBy(rankQuery.getOrderBy());
        }
        PageHelper.offsetPage(rankQuery.getOffset(), rankQuery.getLimit());
         Weekend<Rank> example = Weekend.of(Rank.class);
         WeekendCriteria<Rank,Object> criteria = example.weekendCriteria();
         if (!StringUtils.isEmpty(rankQuery.getUsername())){
             criteria.andEqualTo(Rank::getUsername,rankQuery.getUsername());
         }
         if (!StringUtils.isEmpty(rankQuery.getSearchDate())){
             criteria.andGreaterThanOrEqualTo(Rank::getCdate, rankQuery.getBeginDate());
             criteria.andLessThanOrEqualTo(Rank::getCdate, rankQuery.getEndDate());
         }
         long total = rankMapper.selectCountByExample(example);
        PageResultSet<Rank> resultSet = new PageResultSet<>();
        resultSet.setRows(rankMapper.selectByExample(example));
        resultSet.setTotal(total);
        return resultSet;
    }

    /**
     * 积分汇总数据，
     * @param rankQuery
     * @return
     * 是group by 算法，另外添加，不能在结果集拼凑
     */
    @Override
    public PageResultSet<RankDto> findSummary(RankQuery rankQuery) {

        if (!StringUtils.isEmpty(rankQuery.getOrderBy())){
            PageHelper.orderBy(rankQuery.getOrderBy());
        }
        PageHelper.offsetPage(rankQuery.getOffset(), rankQuery.getLimit());

        List<RankDto> userScoresDtoList =  rankMapper.findDtoByWhere(rankQuery);
        Long total = Long.valueOf(rankMapper.selectDtoCountByWhere(rankQuery).longValue());
        PageResultSet<RankDto> resultSet = new PageResultSet<>();
        resultSet.setRows(userScoresDtoList);
        resultSet.setTotal(total);
        return resultSet;
    }


    private Rank rank = new Rank();
    @Override
    public void importExcel2DataBase(String pathFile) {
        BigExcelUtil bigExcelUtil = BigExcelUtil.getInstance();
        List<Object> objs =  bigExcelUtil.importExcel2Obj(pathFile,Rank.class);
        log.info("读取excel：{}", JSON.toJSONString(objs));
        String username = (String) SecurityUtils.getSubject().getPrincipal();
        List<Rank> userScoresList = objs.stream().map(o ->{
             rank = (Rank) o;
             //消费额积分
             if(rank.getInOut()<0){
                 rank.setCore((new BigDecimal(0)).subtract(rank.getCore()));
             }
             rank.setCoperator(username);
            return (Rank)o;
        }).collect(Collectors.toList());
        createbatch(userScoresList);

    }


}
